<template>
  <div class="container2">
    <vue2-org-tree v-for="(department, index) in tableDataMap" :key="department.ID" :data="tableDataMap[index]"
      class="department" :style="{ left: department.x + 'px', top: department.y + 'px' }" :data-id="department.ID"
      :renderContent="renderContent" :horizontal="false" @on-expand="onExpand" collapsable></vue2-org-tree>
  </div>
</template>

<script>
import interact from 'interactjs';
import Vue2OrgTree from "vue2-org-tree";
import 'vue2-org-tree/dist/style.css'
import { convertListToNames, formatDuration, getDeviceTreeData } from "@/utils/index.js";
import { connrequest2 } from "@/api/firstPage.js"

export default {
  components: { Vue2OrgTree },
  name: 'DepartmentManager',
  data() {
    return {
      tableDataMap: [],
      DepartmentList: [],
    };
  },
  created() {

  },
  mounted() {
  },
  methods: {
    async initialize() {
      await this.GetDepartmentDeviceSumTree();
      await this.GetUICommonParam();     // 获取 DepartmentIDList
      await this.getData();              // 加载数据 + 筛选
      this.$nextTick(() => {
        interact('.department').draggable({
          inertia: true,
          modifiers: [
            interact.modifiers.restrictRect({
              restriction: 'parent',
              endOnly: true
            })
          ],
          listeners: {
            move: this.dragMoveListener
          }
        });
      });
    },
    // 保存移动后的位置
    dragMoveListener(event) {
      const target = event.target;
      const id = parseInt(target.getAttribute('data-id'));
      const department = this.tableDataMap.find(dep => dep.ID === id);
      if (department) {
        // 更新位置
        const x = (department.x || 0) + event.dx;
        const y = (department.y || 0) + event.dy;
        // 更新数据
        department.x = x;
        department.y = y;
        // 更新样式
        target.style.left = `${x}px`;
        target.style.top = `${y}px`;
        // 更新 tableDataMap 中对应的 x 和 y
        this.tableDataMap = this.tableDataMap.map(dep =>
          dep.ID === id ? { ...dep, x, y } : dep
        );
        window.localStorage.setItem('DepLocation', JSON.stringify(this.tableDataMap))
      }
    },
    // 获取要显示哪些部门
    async GetUICommonParam() {
      const data = {
        Filter: {
          FileName: 'param_asset_panoramic.json'
        }
      }
      const res = await connrequest2('GetUICommonParam', data)
      this.DepartmentIDList = res.Data.DeviceObj
    },
    async getData() {
      const sortarr = await getDeviceTreeData('children');
      // 本地位置数据
      const savedDepartments = localStorage.getItem('DepLocation');
      let savedMap = {};
      if (savedDepartments) {
        try {
          const parsedDepartments = JSON.parse(savedDepartments);
          const flattenToMap = (nodes) => {
            nodes.forEach(node => {
              savedMap[node.ID] = node;
              if (Array.isArray(node.children)) {
                flattenToMap(node.children);
              }
            });
          };
          flattenToMap(parsedDepartments);
        } catch (e) {
          console.warn('localStorage 部门位置解析失败');
        }
      }
      // ✅ 1. 递归过滤节点（仅保留 ID 在 this.DepartmentIDList 中的）
      const filterByIDList = (nodes) => {
        return nodes
          .map(node => {
            // 递归处理 children
            if (Array.isArray(node.children)) {
              node.children = filterByIDList(node.children);
            }
            // 如果节点在 ID 列表中或者节点为资产，保留
            const isInList = this.DepartmentIDList.includes(node.ID);
            if (isInList || node.DeviceUUID) {
              return node;
            }
            return null;
          })
          .filter(Boolean); // 移除 null 项
      };
      // ✅ 2. 过滤后的树
      const filteredTree = filterByIDList(sortarr);
      // ✅ 3. 合并位置数据和部门展开状态
      const mergeLocationData = (nodes) => {
        nodes.forEach(node => {
          const savedNode = savedMap[node.ID];
          if (savedNode) {
            this.$set(node, 'x', savedNode.x || 0);
            this.$set(node, 'y', savedNode.y || 0);
            this.$set(node, 'expand', savedNode.expand);
          } else {
            this.$set(node, 'x', 0);
            this.$set(node, 'y', 0);
            this.$set(node, 'expand', true);
          }
          if (Array.isArray(node.children)) {
            mergeLocationData(node.children);
          }
        });
      };
      mergeLocationData(filteredTree);
      this.tableDataMap = filteredTree;
      // ✅ 4. 如果没有localStorage数据，默认数据展开
      if(!savedDepartments){
        this.tableDataMap.forEach(root => {
          this.expandAllNodes([root]);
        });
      }
    },
    onExpand(e, data) {
      if ("expand" in data) {
        data.expand = !data.expand;
        if (!data.expand && data.children) {
          this.collapse(data.children);
        }
      } else {
        this.$set(data, "expand", true);
      }
      window.localStorage.setItem('DepLocation', JSON.stringify(this.tableDataMap))

    },
    collapse(list) {
      var _this = this;
      list.forEach(function (child) {
        if (child.expand) {
          child.expand = false;
        }
        child.children && _this.collapse(child.children);
      });
    },
    expandAllNodes(nodes) {
      nodes.forEach(node => {
        this.$set(node, "expand", true);
        if (Array.isArray(node.children) && node.children.length > 0) {
          this.expandAllNodes(node.children);
        }
      });
    },
    // 状态格式化方法
    formatWorkStatus(row) {
      const map = {
        1: '工作',
        2: '娱乐',
        3: '锁定',
        4: '屏保',
        5: '离线',
        10: '其他'
      }
      return map[row.WorkStatus] || '未知状态' // 处理未定义状态码
    },
    getDepartName(val) {
      const arr = convertListToNames([val], this.DepartmentList, 'ID', 'Name')
      return arr.join(',') || this.RootName
    },
    // 获取部门树
    async GetDepartmentDeviceSumTree() {
      const res = await connrequest2('GetDepartmentDeviceSumTree')
      this.DepartmentList = res.Data.Department
      this.RootName = res.Data.RootName
    },
    renderContent(h, data) {
      if (!data.DeviceUUID) {
        return h('div', {
          style: { width: '280px', height: '100px', display: 'flex', padding: '0', border: '1px solid #0185BA' }
        }, [
          h('div', {
            style: {
              width: '28px', background: '#0185BA', color: '#fff', textAlign: 'center', fontSize: this.getDepartName(data.ID).length > 5 ? '16px' : '18px', display: 'flex', alignItems: 'center', justifyContent: 'center',
              writingMode: 'vertical-rl',
              textOrientation: 'upright',
              whiteSpace: 'nowrap',
              letterSpacing: this.getDepartName(data.ID).length > 5 ? '0px' : '5px',
              paddingRight: '3px'
            }
          }, [h('p', this.getDepartName(data.ID))]),
          h('div', {
            style: { display: 'flex', flexDirection: 'column', justifyContent: 'center' }
          }, [
            h('div', {
              style: { display: 'flex', alignItems: 'center', paddingLeft: '20px' }
            }, [
              h('span', { style: { fontSize: '14px', lineHeight: '20px', color: '#23ce69', width: '120px', textAlign: 'left' } }, `在线：${data.AgentName ? this.onStatus : data.OnlineCount}人`),
              h('span', { style: { fontSize: '14px', lineHeight: '20px', color: '#f36b6e' } }, `离线：${data.AgentName ? this.offStatus : data.OffLineCount}人`)
            ]),
            h('div', { style: { display: 'flex', paddingLeft: '20px' } }, [
              h('span', { style: { fontSize: '14px', lineHeight: '20px', color: '#23ce69', width: '120px', textAlign: 'left' } }, `工作：${data.AgentName ? this.WorkingCount : data.WorkingCount}人`),
              h('span', {
                style: { fontSize: '14px', lineHeight: '20px', color: '#f36b6e' }
              }, `娱乐：${data.AgentName ? this.PlayingCount : data.PlayingCount}人`)
            ]),
            h('div', {
              style: { display: 'flex', paddingLeft: '20px', }
            }, [
              h('span', {
                style: { fontSize: '14px', lineHeight: '20px', color: '#23ce69', width: '120px', textAlign: 'left' }
              }, `其他：${data.AgentName ? this.OtherStatusCount : data.OtherStatusCount}人`),
              h('span', {
                style: { fontSize: '14px', lineHeight: '20px', color: '#f36b6e' }
              }, `离开：${data.AgentName ? this.LeavingCount : data.LeavingCount}人`)
            ]),
            !data.AgentName && h('div', { style: { fontSize: '14px', lineHeight: '20px', color: '#bbb', paddingLeft: '20px', textAlign: 'left' } }, `经理：${data.Manager}（${data.Phone}）`)
          ])
        ]);
      }

      const isOnline = data.Status === 1;
      const RealnameType = data.RealnameType === 1
      return h('div', {
        style: { width: '280px', height: '100px', display: 'flex', padding: '0', border: `1px solid ${isOnline ? '#006E5F' : '#475869'}`, cursor: 'pointer', position: 'relative' }
      }, [
        h('div', {
          style: {
            width: '28px', background: isOnline ? '#006E5F' : '#475869', color: '#fff', textAlign: 'center', lineHeight: '23px', display: 'flex', alignItems: 'center', justifyContent: 'center',
            writingMode: 'vertical-rl',
            textOrientation: 'upright',
            whiteSpace: 'nowrap',
          }
        }, [h('p', `${data.UserName ? data.UserName : '-'}`)]),
        h('div', { style: { display: 'flex', flex: 1, alignItems: 'center' } }, [
          h('div', [h('img', { attrs: { src: data.FileUUID ? `/ProfilePhoto/${data.FileUUID}` : require('../../assets/logo@2x.png') }, style: { width: '50px', height: '50px', marginLeft: '10px', borderRadius: '50%', objectFit: 'cover', opacity: isOnline ? 'none' : '0.5' } })]),
          h('div', [
            h('div', { style: { fontSize: '14px', lineHeight: '20px', color: isOnline ? '#0FCEB4' : '#C6D4E3', fontWeight: '600', paddingLeft: '20px', textAlign: 'left', width: '190px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, `${data.DeviceName ? data.DeviceName : '-'}`),
            h('div', { style: { fontSize: '14px', lineHeight: '20px', color: '#bbb', paddingLeft: '20px', textAlign: 'left', width: '190px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, `工作状态：${this.formatWorkStatus({ WorkStatus: data.WorkStatus })}`),
            h('div', { style: { fontSize: '14px', lineHeight: '20px', color: '#bbb', paddingLeft: '20px', textAlign: 'left', width: '190px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, `${isOnline ? '开机时长' : '离线时长'}：${formatDuration(Date.now() / 1000 - data.CreateTime)}`),
            h('div', { style: { fontSize: '14px', lineHeight: '20px', color: '#bbb', paddingLeft: '20px', textAlign: 'left', width: '190px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, `活跃进程：${data.ActiveProc || '-'}`),
          ]),
          !RealnameType && h('div', { style: { fontSize: '20px', lineHeight: '20px', width: '20px', background: 'red', borderRadius: '50%', color: '#fff', marginTop: '10px', textAlign: 'center', position: 'absolute', right: '10px', bottom: '10px' }, attrs: { title: '没有安装代理' } }, '!')
        ])
      ]);
    },
  }
};
</script>

<style lang="scss" scoped>
.container2 {
  position: relative;
  height: 100%;
  min-height: 600px;
  overflow: hidden;
  background: #041d30;

}

::v-deep .org-tree-node-label .org-tree-node-label-inner {
  padding: 0 !important;
}

::v-deep .org-tree-container {
  background-color: rgba(0, 0, 0, 0);
}

::v-deep .org-tree-node-btn {
  background: #1F466F;
  border: 1px solid #1a527e;
}

::v-deep .org-tree-node-btn:before {
  border-top: 1px solid #1a527e;
}

::v-deep .org-tree-node:not(:first-child):before,
.org-tree-node:not(:last-child):after {
  border-top: 1px solid #1F466F;
}

::v-deep .org-tree-node:after {
  border-left: 1px solid #1F466F;
}

::v-deep .org-tree-node:not(:first-child):before,
::v-deep .org-tree-node:not(:last-child):after {
  border-top: 1px solid #1F466F;
}

::v-deep .org-tree-node-children:before {
  border-left: 1px solid #1F466F;
}

::v-deep .org-tree>.org-tree-node:after {
  border-left: 0 !important;
}

.department {
  position: absolute;
  padding: 10px;
  cursor: move;
}
</style>